# This software is Free Software ( Free as in Freedom ). And it's (c) J.Y.Amihud and
# other contributors 2022. Under the terms of GNU General Public License Version 3 or
# any later version as published by the Free Software Foundation.

import os
import gi
import time
import random
import threading
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import GLib

from modules import ui
from modules import player
from modules import youtube

##########################################################################
#                                                                        #
#                   THE MAIN WINDOW OF PARTY PLAYER                      #
#                                                                        #
##########################################################################

win = Gtk.Window()                    # Make a GTK window object
win.connect("destroy", Gtk.main_quit) # If you close the window, program quits
win.set_title("Party Player")         # Title
#win.set_default_icon_from_file("icon.png") # Icon
win.maximize()

# This software will contain two halves, sideways. So I think we can start by making
# a mainbox horizontal.

mainbox = Gtk.HBox()
win.add(mainbox)

##########################################################################
#                                                                        #
#                      CURRENTLY PLAYING SONG HALF                       #
#                                                                        #
##########################################################################

preview_box = Gtk.VBox()
mainbox.pack_start(preview_box, 1, 1, 1)

# Preview of the current playing

url = "https://invidious.namazso.eu/vi/XGb1W-MPGhk/hqdefault.jpg"
preview_b = Gtk.VBox()
preview = ui.image(win, url, 700)
preview_b.pack_start(preview, 1, 1, 0)
preview_box.pack_start(preview_b, 1,1,0)

def change_current_playing(w, url, title="Nothing"):
    for i in preview_b.get_children():
        i.destroy()
    preview_b.pack_start( ui.image(win, url, 700) , 1, 1, 0)
    preview_b.pack_end( Gtk.Label(title),1,1,5)
    preview_b.show_all()
win.change_preview = change_current_playing

win.chosen = [0]

########################## START PLAYER #############################

# To start the player we will use a few things.

player.load_playlist(win)

win.playindex = 1

win.keep_playing = False
def player_start_stop(w):
    if w.get_active():
        win.keep_playing = True
        play = threading.Thread(target=player.playsong, args=(win,))
        play.start()
    else:
        win.keep_playing = False

playbutton = Gtk.ToggleButton()
playbutton.add(ui.icon("media-playback-start"))
playbutton.connect("clicked", player_start_stop)
playbuttonbox = Gtk.HBox()
playbuttonbox.pack_start(playbutton, 0,0,0)
preview_box.pack_end(playbuttonbox, 0,0,0)

##########################################################################
#                                                                        #
#                              PLAYLIST HALF                             #
#                                                                        #
##########################################################################

list_box = Gtk.VBox()
mainbox.pack_end(list_box,1,1,1)

win.oldplaylist = []
def update_list():
    # This will automatically update the list.
    
    def sendToGtk(win, lbox):
        for i in lbox.get_children():
            i.destroy()
        for i in win.playlist:
            songw = ui.song_render(win, i)
            if not i.get("file"):
                songw.set_sensitive(False)
            lbox.pack_start(songw, 0,0,5)
            lbox.pack_start(Gtk.HSeparator(), 0,0,5)
        lbox.show_all()
        win.oldplaylist = win.playlist.copy()
        
    while True:
        try:
            time.sleep(5)
            
            player.load_playlist(win)
            player.load_reserve(win)

            # Adding a few reserve
            count = 0
            for i in win.playlist:
                if i not in win.reserve_playlist:
                    count += 1
            if ( win.playindex + count ) % 4 == 0 and win.playlist[-1] not in win.reserve_playlist:
                chosen_song = player.choose_random(win)
                win.playlist.append(chosen_song)
                player.save_playlist(win)

            
            if win.oldplaylist != win.playlist:
                print("Updating the list")
                GLib.idle_add(sendToGtk, win, lbox)
                while Gtk.events_pending():
                    Gtk.main_iteration()
        except Exception as e:
            print("Loopfailed", e , "\n\n")

    
listscrl = Gtk.ScrolledWindow()
list_box.pack_start(listscrl, 1, 1, 1)
lbox = Gtk.VBox()
listscrl.add(lbox)

listthread = threading.Thread(target=update_list)
listthread.setDaemon(True)
listthread.start()

###################### ADD BUTTON #########################################

def on_add_song(w):

    # We want to start an add dialog.

    dialog = Gtk.Dialog("Add Song")
    dialog.set_size_request(500,500)
    dbox = dialog.get_content_area()

    # Search entry

    entryfield = Gtk.HBox()
    dbox.pack_start(entryfield, 0,0,5)

    def do_search(w):

        answers = youtube.search(search.get_text())

        for i in listbox.get_children():
            i.destroy()

        for i in answers:

            if i["type"] != "video" or i.get("lengthSeconds", 601) > 600:
                continue
            
            
            song = {"title":i.get("title", "Unknonw"),
                    "videoId":i.get("videoId", ""),
                    "file":None,
                    "picture":i.get("videoThumbnails",[{}])[0].get("url", "")}

            def on_add_song(w, song):
                player.add_song(win, song)
                dialog.destroy()
            
            songbutton = Gtk.Button()
            songbutton.connect("clicked", on_add_song, song)
            songbutton.add(ui.song_render(win, song))
            listbox.pack_start(songbutton, 0,0,5)
            

        listbox.show_all()
    
    search = Gtk.Entry()
    search.connect("activate", do_search)
    entryfield.pack_start(search, 1,1,5)
    searchbutton = Gtk.Button()
    searchbutton.connect("clicked", do_search)
    searchbutton.add(ui.icon("system-search"))
    entryfield.pack_end(searchbutton, 0,0,5)

    # List of findings

    listscrl = Gtk.ScrolledWindow()
    listbox = Gtk.VBox()
    listscrl.add(listbox)
    dbox.pack_end(listscrl, 1,1,5)

    
    listbox.pack_start(Gtk.Label("No Items"), 1,1,0)
    
    dbox.show_all()
    dialog.run()
    dialog.destroy()

addbutton = Gtk.Button()
addbutton.connect("clicked", on_add_song)
addbbox = Gtk.HBox()
addbutton.add(addbbox)
addbbox.pack_start(ui.icon("list-add"), 0,0,0)
list_box.pack_end(addbutton, 0,0,0)



win.show_all()
Gtk.main()
ui.clean_image_cache()
win.keep_playing = False
win.mpv.kill()
